﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using Damany.Windows.Form;
using System.Threading;
using ATM_Pro.Module;
using System.IO;
using ATM_Pro.Log;
using System.Net;
using System.Diagnostics;
using System.Media;
using System.Collections;
using Microsoft.Win32;
using ATM_Pro.Public;
using ATM_Pro.Query;

namespace ATM_Pro
{
    public delegate void ImageDataChangeHandle(object sender, DataChangeEventArgs e);

    public partial class MainForm : Form
    {
        GetTransPacket gtp = null;
        log4net.ILog log = null;
        private IAlarmService _alarmService;

        public MainForm()
        {
            InitializeComponent();
            gtp = new GetTransPacket();
            gtp.ConnectionServerHandle += gtp_ConnectionServerHandle;

            gtp.sph.DataChange += sph_DataChange;//状态信息包事件
            gtp.lph.DataChange += lp_DataChange;//实时图像数据包事件
            gtp.tph.DataChange += tph_DataChange;//交易信息包事件
            gtp.wph.DataChange += wph_DataChange;//报警信息包事件
            gtp.boph.DataChange += boph_DataChange;//遮挡报警信息包事件
            Atms = Configuration.GetInstance().Atms;//初始化ATM和摄像机列表
            log = Log.Log.GetInstance();//初始化 日志类

            var soudAlarm = new SoundAlarmService();
            soudAlarm.CameraCoveredWaveFileName = Properties.Settings.Default.CameraCoveredWaveFileName;
            soudAlarm.ObjectLeftBehindWaveFileName = Properties.Settings.Default.ObjectLeftBehindWaveFileName;

            _alarmService = soudAlarm;
        }

        private System.Threading.Timer paintImageTimer = null;
        private void PaintPictureBox(object sender)
        {
            //PictureBox p = (PictureBox)sender;
            //Pen pp = new Pen(Color.Red);

            //Graphics graphic = p.CreateGraphics();
            //graphic.DrawRectangle(pp,0,0,
            //                             e.ClipRectangle.X + e.ClipRectangle.Width - 1,
            //                            e.ClipRectangle.Y + e.ClipRectangle.Height - 1);
        }

        //当前用户名
        private string UserName { get; set; }

        //程序加载时自动连接
        private void LoadingConnectServer()
        {
            string[] conInfo = Properties.Settings.Default.CurIpAndAddress.Split('|');
            foreach (TreeNode node in tvAllATM.Nodes[0].Nodes)
            {
                ATM atm = (ATM)node.Tag;
                if (atm.AddName.Equals(conInfo[1]) && atm.Ip.Equals(conInfo[0]))
                {
                    this.CurNode = node;
                    break;
                }
            }
            if (this.CurNode != null)
                ConnectionServer(conInfo[0], conInfo[1], Convert.ToInt32(conInfo[2]));
        }

        //初始化 ATM机列表
        private List<ATM> Atms
        {
            set
            {
                tvAllATM.Nodes.Clear();
                TreeNode root = new TreeNode("ATM列表");
                root.ImageIndex = 0;
                root.SelectedImageIndex = 0;
                DataSet ds = new DataSet();

                foreach (ATM atm in value)
                {
                    //TreeNode ATM
                    TreeNode atmNode = new TreeNode(atm.AddName);
                    atmNode.Tag = atm;
                    atmNode.ImageIndex = 1;
                    atmNode.SelectedImageIndex = 1;
                    atmNode.Expand();

                    //TreeNode  Ip
                    TreeNode ipNode = new TreeNode("IP " + atm.Ip);
                    ipNode.ImageIndex = 1;
                    ipNode.SelectedImageIndex = 1;
                    atmNode.Nodes.Add(ipNode);

                    root.Nodes.Add(atmNode);
                }
                tvAllATM.Nodes.Add(root);
                root.Expand();
            }
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
#if DEBUG
            return;
#endif
            UserEnterForm enterForm = new UserEnterForm();//用户登录窗体
            //enterForm.ShowInTaskbar = false;
            if (enterForm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                this.UserName = enterForm.UserName;
                LoadingConnectServer();
            }
            else
            {
                this.Close();
            }
        }

        #region Connect sever
        //连接服务器
        private void ConnectionServer(string ip, string addname, int port)
        {
            lvWarnInfo.Items.Clear();
            picWarn.Image = null;
            picTrans.Image = null;

            gtp.IP = ip;
            gtp.Port = port;
            gtp.AtmAddress = addname;
            Thread th = new Thread(new ParameterizedThreadStart(gtp.InitSocket));
            th.Start();
        }
        //连接状态显示
        private void gtp_ConnectionServerHandle(object sender, DataChangeEventArgs e)
        {
            bool res = Convert.ToBoolean(e.Name);
            if (res)
            {
                ThreadPool.QueueUserWorkItem(obj => gtp.GetData(), null);
                ShowConnectionInfo(e.Ip, e.AtmAddress, res);
            }
            else
            {
                ShowConnectionInfo(e.Ip, e.AtmAddress, res);
            }
        }

        //显示当前连接的ATM机信息
        protected void ShowConnectionInfo(string ip, string addName, bool state)
        {
            CrossThreadOperationControl crossOperation = delegate()
            {
                if (state)
                {
                    this.CurNode.SelectedImageIndex = 1;
                    this.CurNode.ImageIndex = 1;
                    this.CurNode.Text = string.Format("{0} 已连接", addName);
                    Properties.Settings.Default.CurIpAndAddress = ip + "|" + addName + "|" + 10000;
                    Properties.Settings.Default.Save();
                }
                else
                {
                    this.CurNode.SelectedImageIndex = 2;
                    this.CurNode.ImageIndex = 2;
                    this.CurNode.Text = string.Format("{0} 连接失败", addName);
                    this.picHorizon.Image = Image.FromFile(Path.Combine(Application.StartupPath, @"Resources\NoData_wihte.jpg"));
                    this.picVertical.Image = Image.FromFile(Path.Combine(Application.StartupPath, @"Resources\NoData_wihte.jpg"));
                }

            };
            try
            {
                this.Invoke(crossOperation);
                log.Error(string.Format("用户：{0} ATM机：{1} IP：{2} ConnectionState：{3}", this.UserName, addName, ip, state));
            }
            catch (Exception ex)
            {
                string message = string.Format("用户：{0} ATM机：{1} IP：{2} ConnectionState：{3} \r\n {4}", this.UserName, addName, ip, state, ex.Message);
                log.Error(message);
            }
        }

        #endregion

        //用委托改变界面上显示的值
        private delegate void CrossThreadOperationControl();

        #region 状态信息包 sph_DataChange event

        protected void sph_DataChange(object sender, DataChangeEventArgs e)
        {
            StatePacketHandle sph = (StatePacketHandle)sender;
            if (sph != null)
            {
                StatePacketBean spb = sph.StatePackBean;
                ShowCameraState(spb.HorCamState.ToString(), spb.VecCamState.ToString());
            }
        }

        protected void ShowCameraState(string hor, string vec)
        {
            CrossThreadOperationControl crossUpdate = delegate()
            {
                grbHorizon.Text = string.Format("水平摄像机  状态：{0}", hor);
                grbVertical.Text = string.Format("垂直摄像机  状态：{0}", vec);
            };
            tableLayoutPanel1.Invoke(crossUpdate);
        }

        #endregion

        #region 实时信息数据包 lp_DataChange event
        public void lp_DataChange(object sender, DataChangeEventArgs e)
        {
            LivePacketHandle lpb = (LivePacketHandle)sender;
            if (lpb != null)
            {

                ATM atm = lpb.LivePack.AtmBean;
                DateTime dtime = lpb.LivePack.LiveTime.ToLocalTime();
                MemoryStream ms = new MemoryStream(lpb.LivePack.LiveImg);
                System.Drawing.Image img = System.Drawing.Image.FromStream(ms);
                if (atm.Cam.ID == 0)
                {
                    if (this.InvokeRequired)
                    {
                        System.Action<Image> showImg = i => this.picHorizon.Image = i;
                        this.Invoke(showImg, img);
                    }
                }
                else if (atm.Cam.ID == 1)
                {
                    if (this.InvokeRequired)
                    {
                        System.Action<Image> showImg = i => this.picVertical.Image = i;
                        this.Invoke(showImg, img);
                    }
                }
                //else
                //{
                //    if (this.InvokeRequired)
                //    {
                //        System.Action<Image> showImg = i => this.pictureBox3.Image = i;
                //        this.Invoke(showImg, img);
                //    }
                //}
                ms.Close();
                ms.Dispose();
            }
        }

        #endregion

        #region 交易信息数据包 tph_DataChange event
        protected void tph_DataChange(object sender, DataChangeEventArgs e)
        {
            TransPacketHandle tph = (TransPacketHandle)sender;
            if (tph != null)
            {
                ATM atm = tph.TransPackBean.AtmBean;
                byte[] bytes = tph.TransPackBean.FaceImg;
                MemoryStream ms = new MemoryStream(bytes, 60 + tph.TransPackBean.OriginImgLength, tph.TransPackBean.FaceImgLength);
                Image faceImg = Image.FromStream(ms);

                ImageDetail detail = new ImageDetail();
                detail.CaptureTime = tph.TransPackBean.TransTime;
                detail.CardId = tph.TransPackBean.CardId;
                detail.PackType = PacketType.TradeMessage.ToString();
                detail.AtmAddress = Enum.GetName(typeof(AtmAddress), tph.TransPackBean.AtmBean.AddId);
                detail.SavePath = tph.TransPackBean.OriginImgPath;

                ShowTransInfo(faceImg, detail);

                ms.Close();
                ms.Dispose();
            }
        }

        protected void ShowTransInfo(Image img, ImageDetail detail)
        {
            ImageCell icell = new ImageCell();
            icell.Image = img;
            icell.Path = detail.SavePath;
            icell.Text = "交易时间:" + detail.CaptureTime;
            icell.Tag = detail;
            ImageCell[] cell = new ImageCell[] { icell };
            slwTransDisplay.ShowImages(cell);
        }
        #endregion

        #region  报警信息数据包 wph_DataChange event

        protected void wph_DataChange(object sender, DataChangeEventArgs e)
        {
            WarnPacketHandle wph = (WarnPacketHandle)sender;
            if (wph != null)
            {
                WarnPacketBean wpb = wph.WarnPackBean;
                ATM atm = wpb.AtmBean;
                byte[] bytes = wpb.ExceptImg;

                MemoryStream ms = new MemoryStream(bytes, 32, wpb.ExceptImgLength);
                Image img = Image.FromStream(ms);
                ms.Close();
                ms.Dispose();

                ShowWarnInfo(wpb.WarnId.ToString("d5"), wpb.WarnLevel, wpb.WarnType, wpb.WarnTime.ToString(), atm.AddId, wpb.AtmBean.Cam.Name, wpb.Path, wpb.PackLength, wpb.TransPath);
            }
        }

        //显示报警信息到list
        protected void ShowWarnInfo(string warnId, int warnLevel, int warnType, string warnTime, int addId, string camName, string path, int length, string url)
        {
            CrossThreadOperationControl crossAdd = delegate()
            {
                if (tabControl1.SelectedIndex != 1)
                    tabControl1.SelectedIndex = 1;

                if (lvWarnInfo.Items.Count > 30)
                {
                    lvWarnInfo.Items.Clear();

                }
                if (!CheckInfo(warnId))  //查看有无相通编号的ID
                {
                    ListViewItem lvi = new ListViewItem(new string[] { "",warnId, 
                                                                warnLevel.ToString(),
                                                                Enum.GetName(typeof(WarnType), warnType),
                                                                warnTime,
                                                                Enum.GetName(typeof(AtmAddress), addId) ,
                                                                camName,
                                                                path,
                                                                url});
                    lvi.ImageIndex = 2;
                    lvi.SubItems[0].Tag = length.ToString();
                    lvWarnInfo.Items.Add(lvi);
                }

            };
            lvWarnInfo.Invoke(crossAdd);

            _alarmService.NotifyObjectLeftBehind();
        }

        protected bool CheckInfo(string warnId)
        {
            bool hasrow = false;

            if (lvWarnInfo.Items.Count == 0)
            {
                return hasrow;
            }

            for (int i = 0; i < lvWarnInfo.Items.Count; i++)
            {
                ListViewItem lvi = lvWarnInfo.Items[i];
                if (lvi.SubItems[1].Text.Equals(warnId))
                {
                    hasrow = true;
                    break;
                }
            }
            return hasrow;
        }

        #endregion

        #region 遮挡报警信息数据包 boph_DataChange event

        void boph_DataChange(object sender, DataChangeEventArgs e)
        {
            BlockingOutPacketHandle bophd = (BlockingOutPacketHandle)sender;
            if (bophd != null)
            {
                BlockingOutPacketBean bopb = bophd.BlockingOutPacket;

                byte[] bytes = bopb.ExceptImg;

                MemoryStream ms = new MemoryStream(bytes, 20, bopb.ImgLength);
                Image img = Image.FromStream(ms);
                ms.Close();
                ms.Dispose();

                ShowWarnInfo(img, bopb.Path);
            }
        }

        //显示报警信息到list
        protected void ShowWarnInfo(Image img, string imgPath)
        {
            CrossThreadOperationControl crossAdd = delegate()
            {
                if (picAline.Image != null)
                {
                    picAline.Image.Dispose();
                    picAline.Image = null;
                }
                picAline.Image = img;
                // paintImageTimer = new System.Threading.Timer();

            };
            lvWarnInfo.Invoke(crossAdd);

            _alarmService.NotifyCameraCovered();
        }
        #endregion

        #region Control slwTransDisplay register event
        //单击主界面的图片 显示大图片到 左侧 
        private void slwTransDisplay_SelectedCellChanged(object sender, EventArgs e)
        {
            if (this.slwTransDisplay.SelectedCell != null)
            {
                Cell c = slwTransDisplay.SelectedCell; //获得当前选择的图片对象
                ImageDetail detail = (ImageDetail)c.Tag;
                if (c.Path != null)
                {
                    string url = c.Path;
                    if (!File.Exists(url)) return;

                    picEditFullTrans.Image = Image.FromFile(url);
                    lblTransAdd.Text = string.Format("交易地点： {0}", detail.AtmAddress);
                    lblTranTime.Text = string.Format("交易时间： {0}", detail.CaptureTime.ToString());
                    lblTranCard.Text = string.Format("交易卡号： {0}", detail.CardId);
                }
            }
        }

        //双击主界面的图片 显示相关的详细信息
        private void slwTransDisplay_CellDoubleClick(object sender, CellDoubleClickEventArgs args)
        {
            if (slwTransDisplay.SelectedCell != null)
            {
                Cell c = slwTransDisplay.SelectedCell;

                if (c.Path != null)
                {
                    ImageDetailsForm detailsForm = new ImageDetailsForm();
                    detailsForm.Img = (ImageDetail)args.Cell.Tag;
                    detailsForm.ShowDialog();
                }
            }
        }

        #endregion

        #region Control lvWarnInfo lvWarnInfo_SelectedIndexChanged event

        //报警显示的集合中的 listview selelctCHanged 事件
        private void lvWarnInfo_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lvWarnInfo.FocusedItem != null)
            {
                ListViewItem lvi = lvWarnInfo.FocusedItem;
                string path = lvi.SubItems[7].Text;
                string transPath = lvi.SubItems[8].Text;
                //MessageBox.Show(path);
                if (path != "")
                {
                    if (picWarn.Image != null)
                    {
                        picWarn.Image.Dispose();
                        picWarn.Image = null;
                    }
                    if (picTrans.Image != null)
                    {
                        picTrans.Image.Dispose();
                        picTrans.Image = null;
                    }
                    string url = ImageHandle.AnalyzLiveImgFileName(path);//分析获得图片的路径
                    if (url != "")
                        picWarn.Image = Image.FromFile(url);

                    //url = ImageHandle.AnalyzTransImgFileName(path);
                    if (transPath != "")
                        picTrans.Image = Image.FromFile(transPath);


                    QeuryInfoHandle queryInfo = new QeuryInfoHandle();//实例化 查询操作类
                    DataTable dt = queryInfo.GetTransInfoByPath(transPath);
                    if (dt != null && dt.Rows.Count > 0)
                    {
                        DataRow row = dt.Rows[0];
                        lblTransCardID.Text = string.Format("交易卡号 {0}", row["tCardId"].ToString());
                        lblTransTime.Text = string.Format("交易时间 {0}", row["tTransTime"].ToString());
                        lblTransAddress.Text = string.Format("交易地点 {0}", row["Atm_Address"].ToString());
                        lblCameraId.Text = string.Format("照相机位置 {0}", row["Cam_Name"].ToString());
                    }
                    //QeuryInfoHandle queryInfo = new QeuryInfoHandle();
                    //DataTable dt = queryInfo.GetTransInfoByPath(url);
                    //if (dt != null && dt.Rows.Count > 0)
                    //{
                    //    DataRow dr = dt.Rows[0];
                    //    lblTransCardID.Text = string.Format("交易卡号 {0}", dr["tCardId"].ToString());
                    //    lblTransTime.Text = string.Format("交易时间 {0}", dr["tTransTime"].ToString());
                    //    lblTransAddress.Text = string.Format("交易地点 {0}", dr["Atm_Address"].ToString());
                    //    lblCameraId.Text = string.Format("照相机位置 {0}", dr["Cam_Name"].ToString());
                    //}
                }
            }
        }

        #endregion

        #region Control TreeView tvAllATM tvAllATM_MouseDown event

        private void tvAllATM_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                Point clickPoint = new Point(e.X, e.Y);
                TreeNode curNode = tvAllATM.GetNodeAt(clickPoint);
                if (curNode != null)
                {
                    if (curNode.Level == 1 && curNode.IsSelected)
                    {
                        this.CurNode = curNode;
                        curNode.ContextMenuStrip = cmsTreeMenu;
                    }
                }
            }
        }

        private TreeNode CurNode { get; set; }

        #endregion

        #region Control ToolStrip event

        private void tsbChangLayOut_Click(object sender, EventArgs e)
        {
            ToolStripButton tsp = (ToolStripButton)sender;
            int count = Convert.ToInt32(tsp.Text.Trim());
            if (tsp != null)
            {
                if (slwTransDisplay.Visible)
                {
                    slwTransDisplay.NumberOfColumns = count;
                }
            }
        }

        private void tsbDisplayVideo_Click(object sender, EventArgs e)
        {
            if (this.slwTransDisplay.SelectedCell != null)
            {
                Cell c = slwTransDisplay.SelectedCell;
                if (c.Path != null)
                {
                    string filename = Path.GetFileName(c.Path);
                    string url = c.Path.Replace(PacketType.TradeMessage.ToString() + "\\" + Properties.Settings.Default.BigImg, PacketType.RealtimeMessage.ToString());
                    string videoPath = url.Substring(0, url.Length - filename.Length - 1) + ".avi";
                    try
                    {
                        if (File.Exists(videoPath))
                            Process.Start(videoPath);
                        else
                            MessageBox.Show("没有找到相关视频！", "警告");
                    }
                    catch (System.Exception ex)
                    {
                        MessageBox.Show("没有找到默认的视频播放程序！");
                    }

                }
            }
        }

        #endregion

        #region Control MenuStrip1 event

        //报警信息查询 
        private void tsbWarnInfoQuery_Click(object sender, EventArgs e)
        {
            WarnInfoQeury wiq = new WarnInfoQeury();
            wiq.ShowDialog();
        }

        //交易信息查询
        private void tsbTransInfoQuery_Click(object sender, EventArgs e)
        {
            TransInfoQuery tiq = new TransInfoQuery();
            tiq.ShowDialog();
        }

        //系统设置
        private void tsbSysSetting_Click(object sender, EventArgs e)
        {
            OptionsForm optionsForm = new OptionsForm();

            List<ATM> listAtm = new List<ATM>();
            Configuration configu = Configuration.GetInstance();
            foreach (ATM atm in configu.Atms)
            {
                List<Camera> listCam = new List<Camera>();
                foreach (Camera cam in atm.Cams)
                {
                    listCam.Add(new Camera(cam.ID, cam.Name));
                }
                listAtm.Add(new ATM() { ID = atm.ID, AddId = atm.AddId, AddName = atm.AddName, Ip = atm.Ip, Cams = listCam });
            }

            optionsForm.Atms = listAtm;

            if (optionsForm.ShowDialog() == DialogResult.OK)
            {
                this.Atms = optionsForm.Atms;
            }
            configu.Atms = optionsForm.Atms;
            configu.SaveAtmCollection();

            //设置 ATM 遗留物报警时间间隔
            gtp.SendWarnTimePacket(Properties.Settings.Default.AlarmTimeInterval);
        }

        //时间校验
        private void tspCheckAtmSysTime_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("校验时间，ATM机将会重启！", "提示", MessageBoxButtons.OKCancel) == DialogResult.OK)
            {
                gtp.SendCheckSeverTimePacket();
            }
        }

        #endregion

        #region Control tnHandleWarnInfo and btnNot 处理报警信息
        private void btnHandleWarnInfo_Click(object sender, EventArgs e)
        {
            if (lvWarnInfo.Items.Count > 0)
            {
                if (lvWarnInfo.FocusedItem != null)
                {
                    ListViewItem lvi = lvWarnInfo.FocusedItem;
                    string path = lvi.SubItems[7].Text;
                    WarnPacketBean wp = new WarnPacketBean();
                    wp.PackLength = Convert.ToInt32(lvi.SubItems[0].Tag);
                    wp.WarnId = Convert.ToInt32(lvi.SubItems[1].Text);
                    ATM atm = new ATM();
                    string temp = lvi.SubItems[6].Text;
                    Camera cm = new Camera((int)Enum.Parse(typeof(CameraNumber), temp), temp);
                    atm.Cam = cm;
                    wp.AtmBean = atm;
                    gtp.SendWarnPackBack(wp, 0);
                    SetWarnInfoState(lvi);
                }
                else
                {
                    MessageBox.Show("请选择一条报警信息！");
                }
            }
            else
            {
                MessageBox.Show("报警信息列表中无信息可选！");
            }
        }

        protected void SetWarnInfoState(ListViewItem lvi)
        {
            lvi.ImageIndex = 1;
        }

        private void btnNot_Click(object sender, EventArgs e)
        {
            if (lvWarnInfo.Items.Count > 0)
            {
                if (lvWarnInfo.FocusedItem != null)
                {
                    ListViewItem lvi = lvWarnInfo.FocusedItem;
                    string path = lvi.SubItems[7].Text;
                    WarnPacketBean wp = new WarnPacketBean();
                    wp.PackLength = Convert.ToInt32(lvi.SubItems[0].Tag);
                    wp.WarnId = Convert.ToInt32(lvi.SubItems[1].Text);
                    ATM atm = new ATM();
                    string temp = lvi.SubItems[6].Text;
                    Camera cm = new Camera((int)Enum.Parse(typeof(CameraNumber), temp), temp);
                    atm.Cam = cm;
                    wp.AtmBean = atm;
                    gtp.SendWarnPackBack(wp, 1);
                    SetWarnInfoState(lvi);
                }
                else
                {
                    MessageBox.Show("请选择一条报警信息！");
                }
            }
            else
            {
                MessageBox.Show("报警信息列表中无信息可选！");
            }
        }
        #endregion

        private void toolStripButton4_Click(object sender, EventArgs e)
        {

        }

        #region Control ContextMenuStrip event

        private void tsmiView_Click(object sender, EventArgs e)
        {
            if (this.CurNode != null)
            {
                ATM atm = (ATM)this.CurNode.Tag;
                int count = this.CurNode.GetNodeCount(true);
                ConnectionServer(atm.Ip, atm.AddName, 10000);
            }
        }

        private void tsmiCheck_Click(object sender, EventArgs e)
        {
            if (this.CurNode != null)
            {
                if (gtp.AtmAddress != "" && gtp.AtmAddress != null)
                {
                    if (this.CurNode.Text.StartsWith(gtp.AtmAddress))
                    {
                        gtp.SendCheckCameraStatePacket();
                    }
                }
            }
        }

        #endregion

        private void 文件ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SoundPlayer sp = new SoundPlayer("erro.wav");
            sp.Play();
        }



    }

}